package org.xlp.db.xml;

import org.xlp.db.xml.ele.SQLEle;

import java.io.File;

/**
 * 处理sql配置文件应用工具类
 * @see SQLXmlContextApplication
 * @author xlp
 * @version 1.0
 */
public class SQLXmlContextApplicationUtils{
    /**
     * 处理sql配置文件应用
     */
    private final static SQLXmlContextApplication APPLICATION = new SQLXmlContextApplication();

    /**
     * 当前使用处理sql配置文件应用对象
     */
    private static SQLXmlContextApplication application;

    /**
     * 添加处理器
     *
     * @param index   向指定索引添加处理器
     * @param handler 要添加的处理器
     * @throws NullPointerException 假如参数 handler 为null，则抛出该异常
     */
    public static void addHandler(int index, ISQLXmlFileHandler handler) {
        APPLICATION.addHandler(index, handler);
    }

    /**
     * 添加处理器
     *
     * @param handler 要添加的处理器
     * @throws NullPointerException 假如参数 handler 为null，则抛出该异常
     */
    public static void addHandler(ISQLXmlFileHandler handler) {
        APPLICATION.addHandler(handler);
    }

    /**
     * 移除指定位置的处理器
     *
     * @param index
     * @throws IllegalAccessException 假如参数不合理，则抛出该异常
     */
    public static void removeHandler(int index) {
        APPLICATION.removeHandler(index);
    }

    /**
     * 移除所有的处理器
     */
    public static void clearHandler() {
        APPLICATION.clearHandler();
    }


    /**
     * 解析sql xml配置文件
     *
     * @param file sql xml配置文件
     * @throws IllegalArgumentException 假如参数不是xml文件，则抛出该异常
     * @throws NullPointerException     假如参数为null，则抛出该异常
     */
    public synchronized static void parseFile(File file) {
        newSQLXmlContextApplication();
        application.parseFile(file);
    }

    /**
     * 解析sql xml配置文件路径
     *
     * @param filePath sql xml配置文件路径
     * @throws IllegalArgumentException 假如参数不是xml文件，则抛出该异常
     * @throws NullPointerException     假如参数为null，则抛出该异常
     */
    public synchronized static void parseFile(String filePath) {
        newSQLXmlContextApplication();
        application.parseFile(filePath);
    }

    /**
     * 解析给定的目录下所有的sql xml配置文件
     *
     * @param directory sql xml配置文件目录
     * @throws IllegalArgumentException 假如参数不是文件目录，则抛出该异常
     * @throws NullPointerException     假如参数为null，则抛出该异常
     */
    public synchronized static void parseDirectory(File directory) {
        newSQLXmlContextApplication();
        application.parseDirectory(directory);
    }

    /**
     * 解析给定的目录下所有的sql xml配置文件
     *
     * @param directory sql xml配置文件目录
     * @throws IllegalArgumentException 假如参数不是文件目录，则抛出该异常
     * @throws NullPointerException     假如参数为null，则抛出该异常
     */
    public synchronized static void parseDirectory(String directory) {
        newSQLXmlContextApplication();
        application.parseDirectory(directory);
    }

    /**
     * 创建一个新的{@link SQLXmlContextApplication}对象
     */
    private static void newSQLXmlContextApplication() {
        SQLXmlContextApplication application = new SQLXmlContextApplication();
        SQLXmlContextApplicationUtils.APPLICATION.getAllHandlers().forEach(application::addHandler);
        SQLXmlContextApplicationUtils.application = application;
    }

    /**
     * 更据Id获取相应的{@link SQLEle}对象
     *
     * @param parentId {@link SQLsElementInfo}的id值
     * @param id       {@link SQLEle}的id值
     * @return {@link SQLEle}对象
     * @throws NullPointerException 假如参数为null或""，则抛出该异常
     * @throws XmlSQLException 假如未获取到{@link SQLEle}对象，则抛出该异常
     * @see SQLsElementInfo
     * @see SQLEle
     */
    public static SQLEle getSqlEle(String parentId, String id) throws XmlSQLException {
        SQLEle sqlEle = application == null ? null : application.getSqlEle(parentId, id);
        if (sqlEle == null){
            throw new XmlSQLException("未找到parentId = " + parentId + ", id=" + id + "的SQLEle对象");
        }
        return sqlEle;
    }

    /**
     * 把上下文放入缓存中
     */
    public static void putToCache(){
        SQLXmlContextHelper.put(application);
    }
}
